// *****************************************************
// Aitrox Information Technology
// http://www.proxima-ai.com
// Copyright 2021 Aitrox. All rights reserved.
//
// Filename: download.go
// CreateDate: 2023-05-06
// Author: zjp
// Description: 下载数据请求
// ******************************************************
package v1

import (
	"os"
	"strings"
	"usplatformserver/global"
	"usplatformserver/internal/model"
	"usplatformserver/internal/service"
	"usplatformserver/pkg/app"
	"usplatformserver/pkg/commondata"
	"usplatformserver/pkg/errcode"

	"github.com/gin-gonic/gin"
)

// @Summer 下载文件
// @Produce application/zip
// @Param token header string true "token"
// @Param organType query int true "检查部位"
// @Param id query int true "文件ID"
// @Param fileName query string true "文件名"
// @Success 200 {object} model.SwaggerSuccess "成功"
// @Failure 400 {object} errcode.Error "请求错误"
// @Failure 500 {object} errcode.Error "内部错误"
// @Router /api/v1/download [get]
func Download(ctx *gin.Context) {
	param := service.DownloadRequest{}
	response := app.NewResponse(ctx)
	//入参校验
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		response.ToErrorResponse(errcode.InvalidParams.WithDetails(errs.Errors()...))
		return
	}
	fileName := param.FileName
	svc := service.New(ctx.Request.Context())
	//判断下载文件是否存在
	err := svc.Download(&param)
	if err != nil {
		response.ToErrorResponse(err)
		return
	}

	//更新下载次数
	UpdateDownloadTimes(*param.OrganType, *param.ID)
	//回复下载
	response.ToResponseDownload(fileName)
}

// @Summer 通过检查部位获取下载文件列表
// @Param token header string true "token"
// @Param organType query int true "检查类型"
// @Success 200 {object} model.DownloadFileListSwagger "成功"
// @Failure 400 {object} errcode.Error "请求错误"
// @Failure 500 {object} errcode.Error "内部错误"
// @Router /api/v1/download/filelist [get]
func GetDownloadFileList(ctx *gin.Context) {
	param := service.DownloadCommonRequest{}
	response := app.NewResponse(ctx)
	//入参校验
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		response.ToErrorResponse(errcode.InvalidParams.WithDetails(errs.Errors()...))
		return
	}
	svc := service.New(ctx.Request.Context())
	fileList, err := svc.GetDownloadFileList(*param.OrganType)
	if err != nil {
		response.ToErrorResponse(errcode.ErrorGetDownloadFileListFail)
		return
	}
	response.ToResponseListWithoutPager(fileList)
}

/**
 * @brief 插入下载文件数据
 * @param organType-检查部位
 * @param fileName-文件名
 * @return 错误信息
 */
func InsertDownloadFile(organType int, fileName string) error {
	return service.InsertDownloadFile(organType, fileName)
}

/**
 * @brief 更新下载次数
 * @param organType-检查部位
 * @param id-下载文件信息唯一ID
 * @return 错误信息
 */
func UpdateDownloadTimes(organType, id int) error {
	//更新数据库
	err := service.UpdateDownloadTimes(id)
	if err != nil {
		global.Logger.Infof("UpdateDownloadTimes failed: %v", err)
		return err
	}
	//更新内存
	commondata.New().UpdateWaitDownloadCount(organType)
	//发送消息
	err = global.MqttClient.PublishWaitDownloadCount(organType, commondata.New().GetWaitDownloadCount(organType))
	if err != nil {
		global.Logger.Errorf("publishWaitDownloadCount failed: %v", err)
	}
	return nil
}

// @Summer 通过检查部位获取待下载文件个数
// @Param token header string true "token"
// @Param organType query int true "检查类型"
// @Success 200 {object} model.DownloadTimesSwagger "成功"
// @Failure 400 {object} errcode.Error "请求错误"
// @Failure 500 {object} errcode.Error "内部错误"
// @Router /api/v1/download/downloadtimes [get]
func GetDownloadTimes(ctx *gin.Context) {
	response := app.NewResponse(ctx)
	param := service.DownloadCommonRequest{}
	//入参校验
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		response.ToErrorResponse(errcode.InvalidParams.WithDetails(errs.Errors()...))
		return
	}

	count := commondata.New().GetWaitDownloadCount(*param.OrganType)

	response.ToResponse(model.DownloadTimes{DownloadTimes: count})
}

// @Summer 删除下载文件信息
// @Produce application/zip
// @Param token header string true "token"
// @Param organType query int true "检查部位"
// @Param files query string true "文件名集合"
// @Success 200 {object} model.SwaggerSuccess "成功"
// @Failure 400 {object} errcode.Error "请求错误"
// @Failure 500 {object} errcode.Error "内部错误"
// @Router /api/v1/download/filelist [delete]
func DeleteDownloadFiles(ctx *gin.Context) {
	param := service.DeleteFilesRequest{}
	response := app.NewResponse(ctx)
	//入参校验
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		response.ToErrorResponse(errcode.InvalidParams.WithDetails(errs.Errors()...))
		return
	}
	svc := service.New(ctx.Request.Context())
	fileArr := strings.Split(param.Files, ",")
	rowAffected, err := svc.DeleteDownloadFiles(*param.OrganType, fileArr)
	if err != nil {
		global.Logger.Infof("DeleteDownloadFiles failed: %v", err)
		response.ToErrorResponse(errcode.ErrorDeleteFileFail)
		return
	}
	response.ToResponseSuccess()
	if rowAffected > 0 {
		//删除本地文件
		deleteLocalFiles(fileArr)
		//更新待下载文件个数
		commondata.New().UpdateWaitDownloadCount(*param.OrganType)
		//发送通知
		err = global.MqttClient.PublishWaitDownloadCount(*param.OrganType, commondata.New().GetWaitDownloadCount(*param.OrganType))
		if err != nil {
			global.Logger.Errorf("PublishWaitDownloadCount failed: %v", err)
		}
	}
}

func deleteLocalFiles(files []string) {
	var path string
	for _, file := range files {
		path = "./" + file
		if _, err := os.Stat(path); !os.IsNotExist(err) {
			os.Remove(path)
		}
	}
}
